package state.scala

trait TCPState

object Listening extends TCPState {
  def doOpen {}
}

object Established extends TCPState {
  def doClose {}
}

object Closed extends TCPState

abstract class Server[S <: TCPState](host: String, port: Int) {
  val state: S

  def open(implicit ev: S =:= Listening.type) = {
    state.doOpen
    new Server[Established.type](host, port) {
      override val state = Established
    }
  }

  def close(implicit ev: S =:= Established.type) = {
    state.doClose
    new Server[Closed.type](host, port) {
      override val state = Closed
    }
  }
}

object Server {
  def apply(host: String, port: Int) = new Server[Listening.type](host, port) {
    override val state = Listening
  }
}
